package org.ws.edu.core;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.log4j.Logger;
import org.ws.edu.model.Answer;
import org.ws.edu.model.Question;
import org.ws.edu.model.Test;
import org.ws.edu.model.Type;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.XStreamException;

public class TestLoader {
    private static Logger logger = Logger.getLogger(TestLoader.class);
    private static TestLoader tl = null;

    private final HashMap<String, Test> availableTests;
    private final List<String> invalidTestNames;

    private TestLoader(String folderPath) {
        availableTests = new HashMap<String, Test>();
        invalidTestNames = new ArrayList<String>();
        loadFiles(folderPath);

    }

    public static synchronized TestLoader getInstance(String folderPath) {
        if (tl == null) {
            tl = new TestLoader(folderPath);
            logger.info("Instance TestLoader");
        }
        return tl;

    }

    public synchronized String[] getAvailableTestNames() {
        logger.info("get available tests name");
        return availableTests.keySet().toArray(new String[0]);
    }

    public synchronized String[] getInvalidTestNames() {
        logger.info("get invalid tests name");
        return invalidTestNames.toArray(new String[0]);
    }

    public synchronized Test getTest(String name) {
        logger.info("get test: " + name);
        return availableTests.get(name).clone();

    }

    private Test readXmlFiles(String path) {
        XStream xs = new XStream();
        Test e = new Test();

        xs.alias("test", Test.class);
        xs.alias("question", Question.class);
        xs.alias("answer", Answer.class);

        xs.addImplicitCollection(Test.class, "questions");
        xs.addImplicitCollection(Question.class, "allAnswers");

        xs.useAttributeFor(Answer.class, "factor");
        xs.useAttributeFor(Answer.class, "name");
        xs.useAttributeFor(Question.class, "name");
        xs.useAttributeFor(Test.class, "name");

        try {
            FileInputStream in = new FileInputStream(path);
            xs.fromXML(in, e);
            if (e.getType() != Type.SCALES) {
                e.setResult(null);
            }
            return e;
        } catch (FileNotFoundException e2) {
            logger.warn("XML File" + path + " not found", e2);
        }
        return null;
    }

    private void loadFiles(String folderPath) {
        File folderWithTests = new File(folderPath);
        File[] xmlFiles = folderWithTests.listFiles();
        for (int i = 0; i < xmlFiles.length; i++) {
            if (xmlFiles[i].isHidden()) {
                continue;
            }
            try {
                availableTests.put(xmlFiles[i].getName(), readXmlFiles(xmlFiles[i].getPath()));
                logger.info("Load Valid test file" + xmlFiles[i].getName());
            } catch (XStreamException e) {
                logger.warn("Found Invalid Xml File " + xmlFiles[i].getName());
                invalidTestNames.add(xmlFiles[i].getName());
            }
        }

    }
}
